﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using ETL.Common;
using ETL.Common.Logging;
using ETL.Entity;
namespace ETL.DataAccess
{
    public class ProjectActualResourceUsageRepository
    {

        public ETL_ACTUAL_RESOURCE_USAGES GetActualResourceUsage(decimal genActualResourceUsageId)
        {
            var db = new ETLDataEntities();
            var latestResourceUsage = (from a in db.ETL_ACTUAL_RESOURCE_USAGES
                                       where a.GEN_ACTUAL_RESOURCE_USAGE_ID == genActualResourceUsageId
                                       select a).FirstOrDefault();

            return latestResourceUsage;

        }

        public ETL_ACTUAL_RESOURCE_USAGES GetLastActualResourceUsage(string userId, decimal projectId, decimal taskId)
        {
            var db = new ETLDataEntities();

            //select MAX(aru.start_date) from robibs.app_users usr
            //, resource_instances rin
            //, etl_actual_resource_usages aru
            //, tasks tsk
            //, projects prj
            //where usr.dse_id =  rin.resource_name
            //and rin.gen_resource_id = aru.gen_resource_id
            //and aru.gen_task_id = tsk.gen_task_id
            //and tsk.gen_project_id = prj.project_id
            //and usr.dse_id = 'DSE???'

            var latestResourceUsage = (from a in db.ETL_ACTUAL_RESOURCE_USAGES
                                       join t in db.TASKS on a.GEN_TASK_ID equals t.GEN_TASK_ID
                                       join p in db.PROJECTS on t.GEN_PROJECT_ID equals p.PROJECT_ID
                                       join r in db.RESOURCE_INSTANCES on p.PROJECT_NAME equals r.PROJECT_NAME
                                       where r.RESOURCE_NAME == userId && p.PROJECT_ID == projectId && t.TASK_ID == taskId
                                       orderby a.GEN_ACTUAL_RESOURCE_USAGE_ID descending
                                       select a).FirstOrDefault();

            return latestResourceUsage;

        }

        public ETL_ACTUAL_RESOURCE_USAGES GetLastActualResourceUsage(string userId)
        {
            var db = new ETLDataEntities();

            //select MAX(aru.start_date) from robibs.app_users usr
            //, resource_instances rin
            //, etl_actual_resource_usages aru
            //, tasks tsk
            //, projects prj
            //where usr.dse_id =  rin.resource_name
            //and rin.gen_resource_id = aru.gen_resource_id
            //and aru.gen_task_id = tsk.gen_task_id
            //and tsk.gen_project_id = prj.project_id
            //and usr.dse_id = 'DSE???'

            var latestResourceUsage = (from a in db.ETL_ACTUAL_RESOURCE_USAGES
                                       join r in db.RESOURCE_INSTANCES on a.GEN_RESOURCE_ID equals r.GEN_RESOURCE_ID
                                       where r.RESOURCE_NAME.ToLower().Equals(userId.ToLower())
                                       orderby a.GEN_ACTUAL_RESOURCE_USAGE_ID descending
                                       select a).FirstOrDefault();

            return latestResourceUsage;

        }

        public IEnumerable<ETL_ACTUAL_RESOURCE_USAGES> GetListActualResourceUsage(decimal projectId, decimal taskId)
        {
            IEnumerable<ETL_ACTUAL_RESOURCE_USAGES> result = null;

            var db = new ETLDataEntities();
            var allUsages = from s in db.ETL_ACTUAL_RESOURCE_USAGES
                            join t in db.TASKS on s.GEN_TASK_ID equals t.GEN_TASK_ID
                            join p in db.PROJECTS on t.GEN_PROJECT_ID equals p.PROJECT_ID
                            where t.TASK_ID == taskId && t.GEN_PROJECT_ID == projectId 
                            select s;
            if (allUsages.Count() > 0)
            {
                return allUsages;
            }

            return result;
        }

        public void AddNewActualResourceUsage(short? p, short? t, string username, string userid)
        {
            try
            {
                var db = new ETLDataEntities();

                ProjectResourceInstanceRepository _projectResourceRepository = new ProjectResourceInstanceRepository();

                // try to get from db
                RESOURCE_INSTANCES prjActualResourceItem =
                    _projectResourceRepository.GetResourceInstanceByUser(userid);

                // Get last actual resource usages
                /* NOTE */
                // This function should be removed
                var lastGenActualResource = new decimal(0);
                var last =
                    (from a in db.ETL_ACTUAL_RESOURCE_USAGES orderby a.GEN_ACTUAL_RESOURCE_USAGE_ID descending select a).FirstOrDefault();
                if (last != null)
                {
                    lastGenActualResource = last.GEN_ACTUAL_RESOURCE_USAGE_ID;
                }
                lastGenActualResource = lastGenActualResource + 1;
                /* NOTE */

                var time = new ETL_ACTUAL_RESOURCE_USAGES
                {
                    GEN_TASK_ID = t,
                    GEN_ACTUAL_RESOURCE_USAGE_ID = lastGenActualResource,
                    GEN_RESOURCE_ID = prjActualResourceItem.GEN_RESOURCE_ID,
                    START_DATE = DateTime.Now,
                    END_DATE = null
                };

                db.ETL_ACTUAL_RESOURCE_USAGES.Add(time);
                db.SaveChanges();
            }
            catch (Exception ex)
            {
                LogService.Service.Error(ex);
            }

        }
        
        public void UpdateActualResourceUsage(ETL_ACTUAL_RESOURCE_USAGES actual)
        {
            var db = new ETLDataEntities();
            ETL_ACTUAL_RESOURCE_USAGES etlToUpdate = (from s in db.ETL_ACTUAL_RESOURCE_USAGES
                                                      where s.GEN_ACTUAL_RESOURCE_USAGE_ID == actual.GEN_ACTUAL_RESOURCE_USAGE_ID
                                                      select s).First();

            etlToUpdate.START_DATE = actual.START_DATE;
            etlToUpdate.END_DATE = actual.END_DATE;
            etlToUpdate.PERCENT_COMPLETE = actual.PERCENT_COMPLETE;
            etlToUpdate.CLOCKED_OFF_BY = actual.CLOCKED_OFF_BY;
            db.Entry(etlToUpdate).State = EntityState.Modified;

            db.SaveChanges();

        }

        public bool ClockOff(string userid, string username)
        {
            /**
            try
            {
                var db = new ETLDataEntities();
                bool modified = false;
                DateTime startTime;

                int timediff;

                float hours = 0;

                // select records of this user in project_times
                IEnumerable<project_times> lstPrjTime = from s in db.project_times
                                 where
                                     s.time_user_id.Equals(userid) && s.time_notes == null && s.time_finish == null
                                 orderby s.time_start descending
                                 select s;

                if (lstPrjTime != null && lstPrjTime.Count() > 0)
                {
                    var r = lstPrjTime.First();
                    if(r!=null)
                    {
                        if(r.time_finish == null)
                        {
                            if (r.time_start.HasValue)
                            {
                                var dt = r.time_start.Value;
                                timediff = DateTime.Compare(DateTime.Now, dt);
                                modified = false;
                                if(timediff < 0)
                                {
                                    modified = true;
                                    hours = 0;
                                }
                                else
                                {
                                    TimeSpan ts1 = DateTime.Now.Subtract(dt);
                                    hours = Convert.ToSingle(ts1.TotalHours);

                                    if (hours < 0)
                                        hours = 0;

                                    hours *= 100;
                                    hours = Convert.ToInt32(hours);
                                    hours /= 100;
                                }
                            }

                        }
                    }

                }
                db.Dispose();
                db = new ETLDataEntities();
                var lstAll = from s in db.project_times where s.time_name == username && s.time_finish == null select s;
                if(lstAll != null && lstAll.Count() > 0)
                {
                    List<project_times> list = lstAll.ToList();

                    foreach (project_times item in list)
                    {
                        if(modified)
                        {
                            item.time_hours = hours;
                            item.time_start = DateTime.Now;
                            item.time_finish = DateTime.Now;

                        }
                        else
                        {
                            item.time_hours = hours;
                            item.time_finish = DateTime.Now;
                        }

                        db.Entry(item).State = EntityState.Modified;
                        int i = db.SaveChanges();
                        if (i > 0) return true;
                    }
                }

                return false;
            }
            catch (Exception ex)
            {
                LogService.Service.Error(ex);
                return false;
            }
             **/
            return true;
        }
        
        public bool CheckLogOnStatus(string userId)
        {
            try
            {
                var db = new ETLDataEntities();
                bool result = false;
                DateTime startTime = DateTime.Today;

                var listTime = from s in db.ETL_ACTUAL_RESOURCE_USAGES
                               join r in db.RESOURCE_INSTANCES on s.GEN_RESOURCE_ID equals r.GEN_RESOURCE_ID
                               where s.START_DATE > startTime && r.RESOURCE_NAME == userId && s.END_DATE == null
                               select s;
                if (listTime != null && listTime.Count() > 0)
                {
                    var first = listTime.First();
                    if (first != null)
                    {
                        //if (first.time_other != null && !first.time_other.Equals("Program load") && !first.time_other.Equals("Arrived at DSE"))
                        //{
                        //    result = true;
                        //}
                    }
                }
                return result;

            }
            catch (Exception ex)
            {
                LogService.Service.Error(ex);
                return false;
            }

        }

        public int DeleteActualResourceUsages(string taskId)
        {
            try
            {

                var db = new ETLDataEntities();
                decimal dTaskId = Utils.StringToDecimal(taskId);

                // Get Task by genTaskId
                TASK task = (from t in db.TASKS where t.TASK_ID == dTaskId select t).FirstOrDefault();


                if (task != null)
                {
                    var actualResourceUsages = from s in db.ETL_ACTUAL_RESOURCE_USAGES
                                                  where s.GEN_TASK_ID == task.GEN_TASK_ID
                                                  select s;
                    if (actualResourceUsages != null && actualResourceUsages.Count() > 0)
                    {
                        var lstActualResourceUsages = actualResourceUsages.ToList();
                        foreach (var actualResourceUsage in lstActualResourceUsages)
                        {
                            db.ETL_ACTUAL_RESOURCE_USAGES.Remove(actualResourceUsage);
                        }

                        db.SaveChanges();
                    }

                }




                return 1;
            }
            catch (Exception ex)
            {
                LogService.Service.Error(ex);
                return -1;
            }
        }
    }
}
